﻿using System;
using System.Linq;
using Complaint.Models.Dtos;
using Complaint.Models.Dtos.Enums;

namespace Complaint.Repositories
{
    public class OrganisationRepository : BaseRepository<Organisation>, IRepository<Organisation>
    {
        #region IRepository<Organisation> Members

        public void Create(Organisation dto)
        {
            ObjectContext.AddToOrganisation(dto);
            Update(dto);
        }

        public IQueryable<Organisation> FindAll()
        {
            return ObjectContext.Organisation;
        }

        public Organisation FindById(int id)
        {
            return FindAll().FirstOrDefault(o => o.OrganisationID == id);
        }

        public IQueryable<Organisation> FindByName(string name)
        {
            return from organisation in ObjectContext.Organisation
                   where organisation.Name.Contains(name) || organisation.OrganisationAlias.Any(oa => oa.Alias.Contains(name))
                   select organisation;
        }

        #endregion

        public IQueryable<Organisation> FindAll(int pageNumber, int pageSize)
        {
            var count = checked(pageNumber - 1) * pageSize;
            var result = FindAll().OrderBy(o => o.Name).Skip(count).Take(pageSize);

            return result;
        }

        public Organisation FindById(int id, LoadOrganisation loadOption)
        {
            var result = ObjectContext.Organisation.Where(o => o.OrganisationID == id);

            return LoadResult(result, (int)loadOption).FirstOrDefault();
        }

        [Obsolete("This method is obsolete, please use FindById with load option")]
        public Organisation FindByIdWithCategory(int id)
        {
            var org = FindById(id);
            if (!org.Category.IsLoaded)
                org.Category.Load();
            return org;
        }

        public IQueryable<Organisation> FindByCategory(int id)
        {
            return from organisation in ObjectContext.Organisation
                   where organisation.Category.Any(c => c.CategoryID == id)
                   select organisation;
        }

        public IQueryable<Organisation> FindByKeywords(string keywords, LoadOrganisation loadOption)
        {
            var results = FindByName(keywords, loadOption)
                .Union(FindByCategory(keywords, loadOption));

            return results;
        }

        public IQueryable<Organisation> FindByCategory(string name, LoadOrganisation loadOption)
        {
            return from organisation in FindAll(loadOption)
                   where organisation.Category.Any(oc => oc.Title.Contains(name))
                   select organisation;
        }

        public IQueryable<Organisation> FindByName(string name, LoadOrganisation loadOption)
        {
            var result = LoadResult(FindByName(name), (int)loadOption);

            return result;
        }

        public IQueryable<Organisation> FindAll(LoadOrganisation loadOption)
        {
            var result = LoadResult(FindAll(), (int)loadOption);

            return result;
        }

        #region override
        protected override IQueryable<Organisation> LoadResult(IQueryable<Organisation> result, int loadOption)
        {
            if ((loadOption & (int)LoadOrganisation.Alias) == (int)LoadOrganisation.Alias)
            {
                result = result.Include("OrganisationAlias");
            }
            if ((loadOption & (int)LoadOrganisation.Category) == (int)LoadOrganisation.Category)
            {
                result = result.Include("Category");
            }
            if ((loadOption & (int)LoadOrganisation.Complaint) == (int)LoadOrganisation.Complaint)
            {
                result = result.Include("Complaint");
            }
            if ((loadOption & (int)LoadOrganisation.Contact) == (int)LoadOrganisation.Contact)
            {
                result = result.Include("Contact");
            }
            return result;
        }
        #endregion
    }
}